From f87f8a7110e5dd57091b8484685953414693e2a3 Mon Sep 17 00:00:00 2001 From: "kaf24@scramble.cl.cam.ac.uk" Date: Tue, 8 Feb 2005 15:13:45 +0000 Subject: [PATCH] bitkeeper revision 1.1159.250.1 (4208d729hvKh9E4GWJWvFDThd8OXyA) More x86_64 fixes/cleanups. NB. update_va_mapping hypercalls now accept a virtual address, *not* a "virtual page number". Signed-off-by: keir.fraser@cl.cam.ac.uk --- .rootkeys | 2 +- linux-2.4.29-xen-sparse/mm/memory.c | 8 ++--- .../drivers/xen/blkback/blkback.c | 8 ++--- .../drivers/xen/netback/netback.c | 6 ++-- .../drivers/xen/netfront/netfront.c | 4 +-- .../drivers/xen/usbback/usbback.c | 6 ++-- .../include/asm-xen/asm-i386/pgtable.h | 4 +-- .../include/asm-xen/hypervisor.h | 10 +++--- .../sys/arch/xen/include/hypervisor.h | 10 +++--- .../sys/arch/xen/xen/if_xennet.c | 6 ++-- xen/arch/x86/{memory.c => mm.c} | 28 +++++++++------- xen/arch/x86/traps.c | 2 +- xen/common/dom_mem_ops.c | 11 +++---- xen/include/asm-x86/page.h | 7 ++++ xen/include/asm-x86/x86_32/regs.h | 2 ++ xen/include/asm-x86/x86_64/regs.h | 2 ++ xen/include/asm-x86/x86_64/uaccess.h | 33 +++++-------------- 17 files changed, 73 insertions(+), 76 deletions(-) rename xen/arch/x86/{memory.c => mm.c} (99%) diff --git a/.rootkeys b/.rootkeys index d79a03aab0..7a3f24fd75 100644 --- a/.rootkeys +++ b/.rootkeys @@ -867,8 +867,8 @@ 3ddb79bcBit4xJXbwtX0kb1hh2uO1Q xen/arch/x86/idle0_task.c 3ddb79bcKIkRR0kqWaJhe5VUDkMdxg xen/arch/x86/io_apic.c 3ddb79bdqfIcjkz_h9Hvtp8Tk_19Zw xen/arch/x86/irq.c -40ec29ffuOa1ZvmJHzFKyZn4k_RcXg xen/arch/x86/memory.c 41d54a76qfpO0VnbL2tYs0Jgt3W3XA xen/arch/x86/microcode.c +40ec29ffuOa1ZvmJHzFKyZn4k_RcXg xen/arch/x86/mm.c 3ddb79bdS4UeWWXDH-FaBKqcpMFcnw xen/arch/x86/mpparse.c 41aaf566Z4sTDgJ77eEg0TzzQ1ka6Q xen/arch/x86/mtrr/amd.c 41aaf566TOpOBXT00wwQGUh20f1rlA xen/arch/x86/mtrr/centaur.c diff --git a/linux-2.4.29-xen-sparse/mm/memory.c b/linux-2.4.29-xen-sparse/mm/memory.c index 1ae2a42988..7d81c86589 100644 --- a/linux-2.4.29-xen-sparse/mm/memory.c +++ b/linux-2.4.29-xen-sparse/mm/memory.c @@ -915,7 +915,7 @@ static inline void establish_pte(struct vm_area_struct * vma, unsigned long addr #ifdef CONFIG_XEN if ( likely(vma->vm_mm == current->mm) ) { XEN_flush_page_update_queue(); - HYPERVISOR_update_va_mapping(address>>PAGE_SHIFT, entry, UVMF_INVLPG); + HYPERVISOR_update_va_mapping(address, entry, UVMF_INVLPG); } else { set_pte(page_table, entry); flush_tlb_page(vma, address); @@ -1191,7 +1191,7 @@ static int do_swap_page(struct mm_struct * mm, #ifdef CONFIG_XEN if ( likely(vma->vm_mm == current->mm) ) { XEN_flush_page_update_queue(); - HYPERVISOR_update_va_mapping(address>>PAGE_SHIFT, pte, 0); + HYPERVISOR_update_va_mapping(address, pte, 0); } else { set_pte(page_table, pte); XEN_flush_page_update_queue(); @@ -1247,7 +1247,7 @@ static int do_anonymous_page(struct mm_struct * mm, struct vm_area_struct * vma, #ifdef CONFIG_XEN if ( likely(vma->vm_mm == current->mm) ) { XEN_flush_page_update_queue(); - HYPERVISOR_update_va_mapping(addr>>PAGE_SHIFT, entry, 0); + HYPERVISOR_update_va_mapping(addr, entry, 0); } else { set_pte(page_table, entry); XEN_flush_page_update_queue(); @@ -1333,7 +1333,7 @@ static int do_no_page(struct mm_struct * mm, struct vm_area_struct * vma, #ifdef CONFIG_XEN if ( likely(vma->vm_mm == current->mm) ) { XEN_flush_page_update_queue(); - HYPERVISOR_update_va_mapping(address>>PAGE_SHIFT, entry, 0); + HYPERVISOR_update_va_mapping(address, entry, 0); } else { set_pte(page_table, entry); XEN_flush_page_update_queue(); diff --git a/linux-2.6.10-xen-sparse/drivers/xen/blkback/blkback.c b/linux-2.6.10-xen-sparse/drivers/xen/blkback/blkback.c index 6167f6061b..4f74a1c514 100644 --- a/linux-2.6.10-xen-sparse/drivers/xen/blkback/blkback.c +++ b/linux-2.6.10-xen-sparse/drivers/xen/blkback/blkback.c @@ -95,7 +95,7 @@ static void fast_flush_area(int idx, int nr_pages) for ( i = 0; i < nr_pages; i++ ) { mcl[i].op = __HYPERVISOR_update_va_mapping; - mcl[i].args[0] = MMAP_VADDR(idx, i) >> PAGE_SHIFT; + mcl[i].args[0] = MMAP_VADDR(idx, i); mcl[i].args[1] = 0; mcl[i].args[2] = 0; } @@ -343,14 +343,14 @@ static void dispatch_probe(blkif_t *blkif, blkif_request_t *req) #ifdef CONFIG_XEN_BLKDEV_TAP_BE if ( HYPERVISOR_update_va_mapping_otherdomain( - MMAP_VADDR(pending_idx, 0) >> PAGE_SHIFT, + MMAP_VADDR(pending_idx, 0), (pte_t) { (req->frame_and_sects[0] & PAGE_MASK) | __PAGE_KERNEL }, 0, (blkif->is_blktap ? ID_TO_DOM(req->id) : blkif->domid) ) ) goto out; #else if ( HYPERVISOR_update_va_mapping_otherdomain( - MMAP_VADDR(pending_idx, 0) >> PAGE_SHIFT, + MMAP_VADDR(pending_idx, 0), (pte_t) { (req->frame_and_sects[0] & PAGE_MASK) | __PAGE_KERNEL }, 0, blkif->domid) ) @@ -436,7 +436,7 @@ static void dispatch_rw_block_io(blkif_t *blkif, blkif_request_t *req) for ( i = 0; i < nr_psegs; i++ ) { mcl[i].op = __HYPERVISOR_update_va_mapping_otherdomain; - mcl[i].args[0] = MMAP_VADDR(pending_idx, i) >> PAGE_SHIFT; + mcl[i].args[0] = MMAP_VADDR(pending_idx, i); mcl[i].args[1] = (phys_seg[i].buffer & PAGE_MASK) | remap_prot; mcl[i].args[2] = 0; #ifdef CONFIG_XEN_BLKDEV_TAP_BE diff --git a/linux-2.6.10-xen-sparse/drivers/xen/netback/netback.c b/linux-2.6.10-xen-sparse/drivers/xen/netback/netback.c index b75b6169a7..5f5b99cce3 100644 --- a/linux-2.6.10-xen-sparse/drivers/xen/netback/netback.c +++ b/linux-2.6.10-xen-sparse/drivers/xen/netback/netback.c @@ -234,7 +234,7 @@ static void net_rx_action(unsigned long unused) mmu[2].val = MMUEXT_REASSIGN_PAGE; mcl[0].op = __HYPERVISOR_update_va_mapping; - mcl[0].args[0] = vdata >> PAGE_SHIFT; + mcl[0].args[0] = vdata; mcl[0].args[1] = (new_mfn << PAGE_SHIFT) | __PAGE_KERNEL; mcl[0].args[2] = 0; mcl[1].op = __HYPERVISOR_mmu_update; @@ -409,7 +409,7 @@ static void net_tx_action(unsigned long unused) { pending_idx = dealloc_ring[MASK_PEND_IDX(dc++)]; mcl[0].op = __HYPERVISOR_update_va_mapping; - mcl[0].args[0] = MMAP_VADDR(pending_idx) >> PAGE_SHIFT; + mcl[0].args[0] = MMAP_VADDR(pending_idx); mcl[0].args[1] = 0; mcl[0].args[2] = 0; mcl++; @@ -546,7 +546,7 @@ static void net_tx_action(unsigned long unused) skb_reserve(skb, 16); mcl[0].op = __HYPERVISOR_update_va_mapping_otherdomain; - mcl[0].args[0] = MMAP_VADDR(pending_idx) >> PAGE_SHIFT; + mcl[0].args[0] = MMAP_VADDR(pending_idx); mcl[0].args[1] = (txreq.addr & PAGE_MASK) | __PAGE_KERNEL; mcl[0].args[2] = 0; mcl[0].args[3] = netif->domid; diff --git a/linux-2.6.10-xen-sparse/drivers/xen/netfront/netfront.c b/linux-2.6.10-xen-sparse/drivers/xen/netfront/netfront.c index ee53c8b1a6..7e8c434812 100644 --- a/linux-2.6.10-xen-sparse/drivers/xen/netfront/netfront.c +++ b/linux-2.6.10-xen-sparse/drivers/xen/netfront/netfront.c @@ -392,7 +392,7 @@ static void network_alloc_rx_buffers(struct net_device *dev) = INVALID_P2M_ENTRY; rx_mcl[i].op = __HYPERVISOR_update_va_mapping; - rx_mcl[i].args[0] = (unsigned long)skb->head >> PAGE_SHIFT; + rx_mcl[i].args[0] = (unsigned long)skb->head; rx_mcl[i].args[1] = 0; rx_mcl[i].args[2] = 0; } @@ -593,7 +593,7 @@ static int netif_poll(struct net_device *dev, int *pbudget) mmu->val = __pa(skb->head) >> PAGE_SHIFT; mmu++; mcl->op = __HYPERVISOR_update_va_mapping; - mcl->args[0] = (unsigned long)skb->head >> PAGE_SHIFT; + mcl->args[0] = (unsigned long)skb->head; mcl->args[1] = (rx->addr & PAGE_MASK) | __PAGE_KERNEL; mcl->args[2] = 0; mcl++; diff --git a/linux-2.6.10-xen-sparse/drivers/xen/usbback/usbback.c b/linux-2.6.10-xen-sparse/drivers/xen/usbback/usbback.c index 35fcdd84e4..e8ad4e422d 100644 --- a/linux-2.6.10-xen-sparse/drivers/xen/usbback/usbback.c +++ b/linux-2.6.10-xen-sparse/drivers/xen/usbback/usbback.c @@ -191,7 +191,7 @@ static void fast_flush_area(int idx, int nr_pages) for ( i = 0; i < nr_pages; i++ ) { mcl[i].op = __HYPERVISOR_update_va_mapping; - mcl[i].args[0] = MMAP_VADDR(idx, i) >> PAGE_SHIFT; + mcl[i].args[0] = MMAP_VADDR(idx, i); mcl[i].args[1] = 0; mcl[i].args[2] = 0; } @@ -630,7 +630,7 @@ static void dispatch_usb_io(usbif_priv_t *up, usbif_request_t *req) i++, offset += PAGE_SIZE ) { mcl[i].op = __HYPERVISOR_update_va_mapping_otherdomain; - mcl[i].args[0] = MMAP_VADDR(pending_idx, i) >> PAGE_SHIFT; + mcl[i].args[0] = MMAP_VADDR(pending_idx, i); mcl[i].args[1] = ((buffer_mach & PAGE_MASK) + offset) | remap_prot; mcl[i].args[2] = 0; mcl[i].args[3] = up->domid; @@ -646,7 +646,7 @@ static void dispatch_usb_io(usbif_priv_t *up, usbif_request_t *req) { /* Map in ISO schedule, if necessary. */ mcl[i].op = __HYPERVISOR_update_va_mapping_otherdomain; - mcl[i].args[0] = MMAP_VADDR(pending_idx, i) >> PAGE_SHIFT; + mcl[i].args[0] = MMAP_VADDR(pending_idx, i); mcl[i].args[1] = (req->iso_schedule & PAGE_MASK) | remap_prot; mcl[i].args[2] = 0; mcl[i].args[3] = up->domid; diff --git a/linux-2.6.10-xen-sparse/include/asm-xen/asm-i386/pgtable.h b/linux-2.6.10-xen-sparse/include/asm-xen/asm-i386/pgtable.h index 3c0ae34e97..69e0fbf0ba 100644 --- a/linux-2.6.10-xen-sparse/include/asm-xen/asm-i386/pgtable.h +++ b/linux-2.6.10-xen-sparse/include/asm-xen/asm-i386/pgtable.h @@ -426,7 +426,7 @@ extern pte_t *lookup_address(unsigned long address); if (__dirty) { \ if ( likely((__vma)->vm_mm == current->mm) ) { \ xen_flush_page_update_queue(); \ - HYPERVISOR_update_va_mapping((__address)>>PAGE_SHIFT, (__entry), UVMF_INVLPG); \ + HYPERVISOR_update_va_mapping((__address), (__entry), UVMF_INVLPG); \ } else { \ xen_l1_entry_update((__ptep), (__entry).pte_low); \ flush_tlb_page((__vma), (__address)); \ @@ -445,7 +445,7 @@ do { \ do { \ if (likely((__vma)->vm_mm == current->mm)) { \ xen_flush_page_update_queue(); \ - HYPERVISOR_update_va_mapping((__address)>>PAGE_SHIFT, \ + HYPERVISOR_update_va_mapping((__address), \ __entry, 0); \ } else { \ xen_l1_entry_update((__ptep), (__entry).pte_low); \ diff --git a/linux-2.6.10-xen-sparse/include/asm-xen/hypervisor.h b/linux-2.6.10-xen-sparse/include/asm-xen/hypervisor.h index e54caa1b99..f6fcff4e08 100644 --- a/linux-2.6.10-xen-sparse/include/asm-xen/hypervisor.h +++ b/linux-2.6.10-xen-sparse/include/asm-xen/hypervisor.h @@ -438,7 +438,7 @@ HYPERVISOR_multicall( static inline int HYPERVISOR_update_va_mapping( - unsigned long page_nr, pte_t new_val, unsigned long flags) + unsigned long nr, pte_t new_val, unsigned long flags) { int ret; unsigned long ign1, ign2, ign3; @@ -447,13 +447,13 @@ HYPERVISOR_update_va_mapping( TRAP_INSTR : "=a" (ret), "=b" (ign1), "=c" (ign2), "=d" (ign3) : "0" (__HYPERVISOR_update_va_mapping), - "1" (page_nr), "2" ((new_val).pte_low), "3" (flags) + "1" (va), "2" ((new_val).pte_low), "3" (flags) : "memory" ); if ( unlikely(ret < 0) ) { printk(KERN_ALERT "Failed update VA mapping: %08lx, %08lx, %08lx\n", - page_nr, (new_val).pte_low, flags); + va, (new_val).pte_low, flags); BUG(); } @@ -540,7 +540,7 @@ HYPERVISOR_grant_table_op( static inline int HYPERVISOR_update_va_mapping_otherdomain( - unsigned long page_nr, pte_t new_val, unsigned long flags, domid_t domid) + unsigned long va, pte_t new_val, unsigned long flags, domid_t domid) { int ret; unsigned long ign1, ign2, ign3, ign4; @@ -549,7 +549,7 @@ HYPERVISOR_update_va_mapping_otherdomain( TRAP_INSTR : "=a" (ret), "=b" (ign1), "=c" (ign2), "=d" (ign3), "=S" (ign4) : "0" (__HYPERVISOR_update_va_mapping_otherdomain), - "1" (page_nr), "2" ((new_val).pte_low), "3" (flags), "4" (domid) : + "1" (va), "2" ((new_val).pte_low), "3" (flags), "4" (domid) : "memory" ); return ret; diff --git a/netbsd-2.0-xen-sparse/sys/arch/xen/include/hypervisor.h b/netbsd-2.0-xen-sparse/sys/arch/xen/include/hypervisor.h index 035495d4be..eb91c2a980 100644 --- a/netbsd-2.0-xen-sparse/sys/arch/xen/include/hypervisor.h +++ b/netbsd-2.0-xen-sparse/sys/arch/xen/include/hypervisor.h @@ -398,7 +398,7 @@ HYPERVISOR_multicall(void *call_list, int nr_calls) } static inline int -HYPERVISOR_update_va_mapping(unsigned long page_nr, unsigned long new_val, +HYPERVISOR_update_va_mapping(unsigned long va, unsigned long new_val, unsigned long flags) { int ret; @@ -408,12 +408,12 @@ HYPERVISOR_update_va_mapping(unsigned long page_nr, unsigned long new_val, TRAP_INSTR : "=a" (ret), "=b" (ign1), "=c" (ign2), "=d" (ign3) : "0" (__HYPERVISOR_update_va_mapping), - "1" (page_nr), "2" (new_val), "3" (flags) + "1" (va), "2" (new_val), "3" (flags) : "memory" ); if (__predict_false(ret < 0)) panic("Failed update VA mapping: %08lx, %08lx, %08lx", - page_nr, new_val, flags); + va, new_val, flags); return ret; } @@ -494,7 +494,7 @@ HYPERVISOR_grant_table_op(unsigned int cmd, void *uop, unsigned int count) } static inline int -HYPERVISOR_update_va_mapping_otherdomain(unsigned long page_nr, +HYPERVISOR_update_va_mapping_otherdomain(unsigned long va, unsigned long new_val, unsigned long flags, domid_t domid) { int ret; @@ -504,7 +504,7 @@ HYPERVISOR_update_va_mapping_otherdomain(unsigned long page_nr, TRAP_INSTR : "=a" (ret), "=b" (ign1), "=c" (ign2), "=d" (ign3), "=S" (ign4) : "0" (__HYPERVISOR_update_va_mapping_otherdomain), - "1" (page_nr), "2" (new_val), "3" (flags), "4" (domid) : + "1" (va), "2" (new_val), "3" (flags), "4" (domid) : "memory" ); return ret; diff --git a/netbsd-2.0-xen-sparse/sys/arch/xen/xen/if_xennet.c b/netbsd-2.0-xen-sparse/sys/arch/xen/xen/if_xennet.c index 9d8618923c..e1063b1775 100644 --- a/netbsd-2.0-xen-sparse/sys/arch/xen/xen/if_xennet.c +++ b/netbsd-2.0-xen-sparse/sys/arch/xen/xen/if_xennet.c @@ -580,7 +580,7 @@ xennet_rx_push_buffer(struct xennet_softc *sc, int id) INVALID_P2M_ENTRY; rx_mcl[nr_pfns].op = __HYPERVISOR_update_va_mapping; - rx_mcl[nr_pfns].args[0] = sc->sc_rx_bufa[id].xb_rx.xbrx_va >> PAGE_SHIFT; + rx_mcl[nr_pfns].args[0] = sc->sc_rx_bufa[id].xb_rx.xbrx_va; rx_mcl[nr_pfns].args[1] = 0; rx_mcl[nr_pfns].args[2] = 0; @@ -679,7 +679,7 @@ xen_network_handler(void *arg) mmu->val = (pa - XPMAP_OFFSET) >> PAGE_SHIFT; mmu++; mcl->op = __HYPERVISOR_update_va_mapping; - mcl->args[0] = sc->sc_rx_bufa[rx->id].xb_rx.xbrx_va >> PAGE_SHIFT; + mcl->args[0] = sc->sc_rx_bufa[rx->id].xb_rx.xbrx_va; mcl->args[1] = (rx->addr & PG_FRAME) | PG_V|PG_KW; mcl->args[2] = UVMF_FLUSH_TLB; // 0; mcl++; @@ -872,7 +872,7 @@ network_alloc_rx_buffers(struct xennet_softc *sc) INVALID_P2M_ENTRY; rx_mcl[nr_pfns].op = __HYPERVISOR_update_va_mapping; - rx_mcl[nr_pfns].args[0] = va >> PAGE_SHIFT; + rx_mcl[nr_pfns].args[0] = va; rx_mcl[nr_pfns].args[1] = 0; rx_mcl[nr_pfns].args[2] = 0; diff --git a/xen/arch/x86/memory.c b/xen/arch/x86/mm.c similarity index 99% rename from xen/arch/x86/memory.c rename to xen/arch/x86/mm.c index 36a1463001..c2f87ee4d4 100644 --- a/xen/arch/x86/memory.c +++ b/xen/arch/x86/mm.c @@ -1,8 +1,8 @@ /* -*- Mode:C; c-basic-offset:4; tab-width:4; indent-tabs-mode:nil -*- */ /****************************************************************************** - * arch/x86/memory.c + * arch/x86/mm.c * - * Copyright (c) 2002-2004 K A Fraser + * Copyright (c) 2002-2005 K A Fraser * Copyright (c) 2004 Christian Limpach * * This program is free software; you can redistribute it and/or modify @@ -277,8 +277,8 @@ int map_ldt_shadow_page(unsigned int off) if ( unlikely(in_irq()) ) BUG(); - __get_user(l1e, (unsigned long *)&linear_pg_table[(ed->arch.ldt_base >> - PAGE_SHIFT) + off]); + __get_user(l1e, (unsigned long *) + &linear_pg_table[l1_linear_offset(ed->arch.ldt_base) + off]); if ( unlikely(!(l1e & _PAGE_PRESENT)) || unlikely(!get_page_and_type(&frame_table[l1e >> PAGE_SHIFT], @@ -1552,7 +1552,7 @@ int do_mmu_update( } -int do_update_va_mapping(unsigned long page_nr, +int do_update_va_mapping(unsigned long va, unsigned long val, unsigned long flags) { @@ -1564,7 +1564,7 @@ int do_update_va_mapping(unsigned long page_nr, perfc_incrc(calls_to_update_va); - if ( unlikely(page_nr >= (HYPERVISOR_VIRT_START >> PAGE_SHIFT)) ) + if ( unlikely(!__addr_ok(va)) ) return -EINVAL; LOCK_BIGLOCK(d); @@ -1576,7 +1576,7 @@ int do_update_va_mapping(unsigned long page_nr, * the case of updating L2 entries. */ - if ( unlikely(!mod_l1_entry(&linear_pg_table[page_nr], + if ( unlikely(!mod_l1_entry(&linear_pg_table[l1_linear_offset(va)], mk_l1_pgentry(val))) ) err = -EINVAL; @@ -1587,7 +1587,7 @@ int do_update_va_mapping(unsigned long page_nr, l1pte_propagate_from_guest(d, &val, &sval); if ( unlikely(__put_user(sval, ((unsigned long *)( - &shadow_linear_pg_table[page_nr])))) ) + &shadow_linear_pg_table[l1_linear_offset(va)])))) ) { /* * Since L2's are guranteed RW, failure indicates the page was not @@ -1602,7 +1602,7 @@ int do_update_va_mapping(unsigned long page_nr, * for this. */ if ( d->arch.shadow_mode == SHM_logdirty ) - mark_dirty(d, va_to_l1mfn(page_nr << PAGE_SHIFT)); + mark_dirty(d, va_to_l1mfn(va)); check_pagetable(d, ed->arch.pagetable, "va"); /* debug */ } @@ -1614,7 +1614,7 @@ int do_update_va_mapping(unsigned long page_nr, unlikely(flags & UVMF_FLUSH_TLB) ) local_flush_tlb(); else if ( unlikely(flags & UVMF_INVLPG) ) - __flush_tlb_one(page_nr << PAGE_SHIFT); + __flush_tlb_one(va); if ( unlikely(deferred_ops & DOP_RELOAD_LDT) ) (void)map_ldt_shadow_page(0); @@ -1624,7 +1624,7 @@ int do_update_va_mapping(unsigned long page_nr, return err; } -int do_update_va_mapping_otherdomain(unsigned long page_nr, +int do_update_va_mapping_otherdomain(unsigned long va, unsigned long val, unsigned long flags, domid_t domid) @@ -1643,7 +1643,7 @@ int do_update_va_mapping_otherdomain(unsigned long page_nr, return -ESRCH; } - rc = do_update_va_mapping(page_nr, val, flags); + rc = do_update_va_mapping(va, val, flags); put_domain(d); percpu_info[cpu].foreign = NULL; @@ -1994,6 +1994,10 @@ int ptwr_do_page_fault(unsigned long addr) int which, cpu = smp_processor_id(); u32 l2_idx; +#ifdef __x86_64__ + return 0; /* Writable pagetables need fixing for x86_64. */ +#endif + /* * Attempt to read the PTE that maps the VA being accessed. By checking for * PDE validity in the L2 we avoid many expensive fixups in __get_user(). diff --git a/xen/arch/x86/traps.c b/xen/arch/x86/traps.c index 301d7a765e..d867cd8f12 100644 --- a/xen/arch/x86/traps.c +++ b/xen/arch/x86/traps.c @@ -522,7 +522,7 @@ asmlinkage int do_general_protection(struct xen_regs *regs) /* Emulate some simple privileged instructions when exec'ed in ring 1. */ if ( (regs->error_code == 0) && - RING_1(regs) && + GUESTOS_FAULT(regs) && emulate_privileged_op(regs) ) return 0; diff --git a/xen/common/dom_mem_ops.c b/xen/common/dom_mem_ops.c index d5c272e301..f1a7ee0c8c 100644 --- a/xen/common/dom_mem_ops.c +++ b/xen/common/dom_mem_ops.c @@ -122,7 +122,7 @@ free_dom_mem(struct domain *d, long do_dom_mem_op(unsigned long op, unsigned long *extent_list, - unsigned long nr_extents, + unsigned int nr_extents, unsigned int extent_order, domid_t domid) { @@ -133,8 +133,7 @@ do_dom_mem_op(unsigned long op, start_extent = op >> START_EXTENT_SHIFT; op &= (1 << START_EXTENT_SHIFT) - 1; - if ( unlikely(start_extent > nr_extents) || - unlikely(nr_extents > ~0U) ) /* can pack into a uint? */ + if ( unlikely(start_extent > nr_extents) ) return -EINVAL; if ( likely(domid == DOMID_SELF) ) @@ -150,13 +149,11 @@ do_dom_mem_op(unsigned long op, { case MEMOP_increase_reservation: rc = alloc_dom_mem( - d, extent_list, start_extent, - (unsigned int)nr_extents, extent_order); + d, extent_list, start_extent, nr_extents, extent_order); break; case MEMOP_decrease_reservation: rc = free_dom_mem( - d, extent_list, start_extent, - (unsigned int)nr_extents, extent_order); + d, extent_list, start_extent, nr_extents, extent_order); break; default: rc = -ENOSYS; diff --git a/xen/include/asm-x86/page.h b/xen/include/asm-x86/page.h index 06346dc9d9..7f3dad32fb 100644 --- a/xen/include/asm-x86/page.h +++ b/xen/include/asm-x86/page.h @@ -99,6 +99,13 @@ typedef struct { unsigned long l4_lo; } l4_pgentry_t; (((_a) >> L4_PAGETABLE_SHIFT) & (ENTRIES_PER_L4_PAGETABLE - 1)) #endif +/* Given a virtual address, get an entry offset into a linear page table. */ +#if defined(__i386__) +#define l1_linear_offset(_a) ((_a) >> PAGE_SHIFT) +#elif defined(__x86_64__) +#define l1_linear_offset(_a) (((_a) & ((1UL << 48) - 1)) >> PAGE_SHIFT) +#endif + #if defined(__i386__) #define pagetable_t l2_pgentry_t #define pagetable_val(_x) ((_x).l2_lo) diff --git a/xen/include/asm-x86/x86_32/regs.h b/xen/include/asm-x86/x86_32/regs.h index e28f17fba6..ca05876ac6 100644 --- a/xen/include/asm-x86/x86_32/regs.h +++ b/xen/include/asm-x86/x86_32/regs.h @@ -39,4 +39,6 @@ struct xen_regs #define RING_2(_r) (((_r)->cs & 3) == 2) #define RING_3(_r) (((_r)->cs & 3) == 3) +#define GUESTOS_FAULT(_r) (!VM86_MODE(_r) && RING_1(_r)) + #endif diff --git a/xen/include/asm-x86/x86_64/regs.h b/xen/include/asm-x86/x86_64/regs.h index 0169109fe3..d09bddccdb 100644 --- a/xen/include/asm-x86/x86_64/regs.h +++ b/xen/include/asm-x86/x86_64/regs.h @@ -36,4 +36,6 @@ struct xen_regs #define RING_2(_r) (((_r)->cs & 3) == 2) #define RING_3(_r) (((_r)->cs & 3) == 3) +#define GUESTOS_FAULT(_r) (!VM86_MODE(_r) && RING_3(_r)) + #endif diff --git a/xen/include/asm-x86/x86_64/uaccess.h b/xen/include/asm-x86/x86_64/uaccess.h index da3d8f5c1f..bb23ae81a4 100644 --- a/xen/include/asm-x86/x86_64/uaccess.h +++ b/xen/include/asm-x86/x86_64/uaccess.h @@ -15,34 +15,19 @@ #define VERIFY_READ 0 #define VERIFY_WRITE 1 -#define __addr_ok(addr) ((unsigned long)(addr) < HYPERVISOR_VIRT_START) - /* - * Test whether a block of memory is a valid user space address. - * Returns 0 if the range is valid, nonzero otherwise. - * - * This is equivalent to the following test: - * ((u65)addr >= (u65)HYPERVISOR_VIRT_END) ? - * (((u65)addr + (u65)size) >= ((u65)1 << 64)) : - * (((u65)addr + (u65)size) >= ((u65)HYPERVISOR_VIRT_START)) + * Valid if in +ve half of 48-bit address space, or above Xen-reserved area. + * This is also valid for range checks (addr, addr+size). As long as the + * start address is outside the Xen-reserved area then we will access a + * non-canonical address (and thus fault) before ever reaching VIRT_START. */ -#define __range_not_ok(addr,size) ({ \ - unsigned long flag,sum; \ - if ((unsigned long)addr >= HYPERVISOR_VIRT_END) \ - asm("addq %3,%1 ; sbbq %0,%0" \ - :"=&r" (flag), "=r" (sum) \ - :"1" (addr),"g" ((long)(size))); \ - else \ - asm("addq %3,%1 ; sbbq %0,%0 ; cmpq %1,%4 ; sbbq $0,%0" \ - :"=&r" (flag), "=r" (sum) \ - :"1" (addr),"g" ((long)(size)),"r" (HYPERVISOR_VIRT_START)); \ - flag; }) +#define __addr_ok(addr) \ + (((unsigned long)(addr) < (1UL<<48)) || \ + ((unsigned long)(addr) >= HYPERVISOR_VIRT_END)) -#define access_ok(type, addr, size) (__range_not_ok(addr,size) == 0) +#define access_ok(type, addr, size) (__addr_ok(addr)) -#define array_access_ok(type,addr,count,size) \ - (likely(sizeof(count) <= 4) /* disallow 64-bit counts */ && \ - access_ok(type,addr,(unsigned long)count*(unsigned long)size)) +#define array_access_ok(type,addr,count,size) (__addr_ok(addr)) extern long __get_user_bad(void); extern void __put_user_bad(void); -- 2.30.2